<!-- 地图 -->
<template>
  <div class="cons">
    <div id="map"></div>
    <DevicePixel v-if="state.pixelShow" :pixel="state.pixel" :features="state.features" @close="pixelClose" />
  </div>
</template>
<script setup lang='ts'>
import { shallowRef, watch, reactive } from 'vue'
import { queryGeomGet } from '@/api/usemap'
import { GroupNum } from "@/uilts"
import DevicePixel from './info/DevicePixel.vue'
import axios from 'axios'
import useMap from '@/components/UseAMap/index'
import useSettingStore from '@/store/modules/setting'
const SettingStore = useSettingStore()
const wmsUrl = import.meta.env.VITE_WMS_URL
const [map, amap] = useMap('map', {
  zoom: 9,
  center: [114.2783030, 30.49570788],
  mapStyle: 'amap://styles/dark'
}, initMap)
const $emit = defineEmits(['polygonClick'])
const state = reactive<any>({
  layerList: ['lamp', 'lamp_post', 'loop', 'transformer', 'single_lamp', 'lamp_post_tailpiece'],
  pixel: {
    top: 0,
    left: 0
  },
  pixelShow: false,
  features: [],
  range: 30
})
//  地图初始化
const mouseTool = shallowRef()
function initMap() {
  layerDraw()
  queryGeomAjax('type_1')

  //  绘制矢量图形
  mouseTool.value = new amap.value.MouseTool(map.value)
  mouseTool.value.on('draw', (event: any) => {
    drawHandler(event)
  })
  //  地图缩放
  map.value.on('zoomend', () => {
    const zoom = map.value.getZoom()
    SettingStore.zoom = parseInt(zoom)
    if (polygonLayer.value) {
      if (zoom < 12) {
        polygonLayer.value.show()
        textLayer.value.show()
      } else {
        polygonLayer.value.hide()
        textLayer.value.hide()
      }
    }
    layerDrawShow()

    state.pixelShow = false
    if (zoom < 13 && zoom >= 12) {
      state.range = 5120
    } else if (zoom < 14 && zoom >= 13) {
      state.range = 2560
    } else if (zoom < 15 && zoom >= 14) {
      state.range = 1280
    } else if (zoom < 16 && zoom >= 15) {
      state.range = 640
    } else if (zoom < 17 && zoom >= 16) {
      state.range = 320
    } else if (zoom < 18 && zoom >= 17) {
      state.range = 160
    } else if (zoom < 19 && zoom >= 18) {
      state.range = 80
    } else if (zoom < 20 && zoom >= 19) {
      state.range = 40
    } else {
      state.range = 20
    }
  })
  //  地图拖拽开始
  map.value.on('dragstart', () => {
    state.pixelShow = false
  })
  //  地图拖拽结束
  map.value.on('dragend', () => {

  })
  //  地图点击
  map.value.on('click', (e: any) => {
    state.pixel.top = e.pixel.y
    state.pixel.left = e.pixel.x
    state.pixelShow = false
    const { pos } = e
    const range = [pos[0] - state.range, pos[1] - state.range, pos[0] + state.range, pos[1] + state.range].join()
    searchWms(range)
  })
}
//  切换主题
watch(() => SettingStore.mapTheme, (newVal) => {
  const type = newVal ? 'grey' : 'normal'
  map.value.setMapStyle(`amap://styles/${type}`)
  layerDraw()
  // for (let i = 0; i < state.layerList.length; i++) {
  //   let item = state.layerList[i];
  //   state[item].reload()
  // }
})
//  设备弹框关闭
const pixelClose = () => {
  state.pixelShow = false
}
//  点击搜索
const searchWms = async (bbox: string) => {
  state.features = []
  try {
    const { data } = await axios({
      url: `${wmsUrl}/geoserver/ty/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&FORMAT=image%2Fpng&TRANSPARENT=true&QUERY_LAYERS=ty%3Aview_device_columns&STYLES&LAYERS=ty%3Aview_device_columns&exceptions=application%2Fvnd.ogc.se_inimage&INFO_FORMAT=application%2Fjson&FEATURE_COUNT=10&X=50&Y=50&SRS=EPSG%3A3857&WIDTH=101&HEIGHT=101&BBOX=${bbox}`,
      method: 'GET',
    })
    if (data.features.length > 0) {
      state.features = data.features
      state.pixelShow = true
    } else {
      state.pixelShow = false
    }
  } catch (error) {

  }

}
//  行政区、管理单位、中心运维
const queryGeomAjax = async (value: string) => {
  try {
    const { data } = await queryGeomGet(value)
    if (data) {
      data.forEach((item: any) => {
        item.geoStr = JSON.parse(item.geoStr)
      })
      polygonLayerDraw(data)
      textLayerDraw(data)
    }
  } catch (error) {
    console.log(error)
  }
}
//  画行政区
const polygonLayer = shallowRef()
const polygonLayerDraw = (list: any[]) => {
  if (polygonLayer.value) {
    polygonLayer.value.clearOverlays()
  }
  if (list.length > 0) {
    const array = []
    const colors = ['#2672FF', '#4A95FF', '#00A0CE', '#07C9D6', '#00D90F', '#00CF70', '#FFD74A', '#25FFAA', '#6C4AFF', '#B77DFF', '#FF4393', '#FF6E6E', '#FF904A']
    for (let i = 0; i < list.length; i++) {
      const item = list[i]
      if (item.geoStr && item.geoStr.coordinates) {
        const polygon = new amap.value.Polygon({
          path: item.geoStr.coordinates,
          strokeColor: "#001234",
          strokeWeight: 2,
          strokeOpacity: 0.8,
          fillOpacity: 0.4,
          fillColor: colors[i],
          cursor: 'pointer',
          zIndex: 50,
          extData: item
        })
        array.push(polygon)
        polygon.on('click', (e: any) => {
          polygonHandler(e)
        })
      }
    }
    //  矩形集合
    polygonLayer.value = new amap.value.OverlayGroup(array)
    // 对此覆盖物群组设置同一属性
    polygonLayer.value.setOptions({})
    map.value.add(polygonLayer.value)
  }
}
//  区域点击交互
const polygonHandler = (e: any) => {
  const list = polygonLayer.value.getOverlays()
  for (let i = 0; i < list.length; i++) {
    const item = list[i];
    if (item._opts.extData.name === e.target._opts.extData.name) {
      item.setOptions({
        strokeColor: '#FFF',
        zIndex: 99
      })
    } else {
      item.setOptions({
        strokeColor: '#001234'
      })
    }
  }
  $emit('polygonClick', e.target._opts.extData)
}
//  纯文本标记
const textLayer = shallowRef()
const textLayerDraw = (list: any[]) => {
  const mapText = WarehouseStore.mapText
  if (textLayer.value) {
    textLayer.value.clearOverlays()
  }
  if (list.length > 0) {
    const array = []
    for (let i = 0; i < list.length; i++) {
      const item = list[i]
      if (item.geoStr && item.geoStr.coordinates) {
        const content = `<div  style='width: 200px;text-align: center;'>
          <span style="font-size: 14px; color: #fff; text-shadow: 0 2px #001234, 2px 0 #001234, -2px 0 #001234, 0 -2px #001234">${item.name}</span>
          <p style="font-size: 13px; color: #fff;margin-top: 5px;text-shadow: 0 2px #001234, 2px 0 #001234, -2px 0 #001234, 0 -2px #001234"">变压器:${mapText[item.name].transformer} 灯杆:${mapText[item.name].lampPost} 灯:${mapText[item.name].lamp}</p>
        </div>`
        const text = new amap.value.Marker({
          content,
          position: [item.lng, item.lat],
          offset: [-100, 0],
          extData: item
        })
        array.push(text)
      }
    }
    //  文本集合
    textLayer.value = new amap.value.OverlayGroup(array)
    // 对此覆盖物群组设置同一属性
    textLayer.value.setOptions({})
    map.value.add(textLayer.value)
  }
}
//  各图层
const layerDraw = () => {
  const zIndexS = [99, 98, 97, 96]
  for (let i = 0; i < state.layerList.length; i++) {
    let item = state.layerList[i];
    if (state[item]) {
      state[item].setMap(null)
    }
    let params: any = {
      SERVICE: "WMTS",
      LAYER: `ty:${item}`,
      FORMAT: "image/png",
      VERSION: "1.0.0",
    }
    if (SettingStore.mapTheme && item === 'lamp_post') {
      params.style = 'ty:lamp_post_1'
    }
    state[item] = new amap.value.TileLayer.WMTS({
      url: `${wmsUrl}/geoserver/ty/gwc/service/wmts`,
      blend: true, // 地图级别切换时，不同级别的图片是否进行混合
      tileSize: 256, // 加载WMS图层服务时，图片的分片大小
      zIndex: zIndexS[i],
      dataZooms: [1, 20],
      params
    })
    state[item].setMap(map.value)
    const zoom = map.value.getZoom()
    if (zoom < 12) {
      state[item].hide()
    }
  }
}
//  图层显示隐藏
const layerDrawShow = () => {
  for (let i = 0; i < state.layerList.length; i++) {
    const item = state.layerList[i];
    if (SettingStore.layerList.indexOf(item) > -1 && SettingStore.zoom >= 12) {
      state[item].show()
    } else {
      state[item].hide()
    }
  }
}
//  图层显示隐藏
watch(() => SettingStore.layerList, () => {
  layerDrawShow()
})
//  几个图层 框选点
const TileLayer = shallowRef()
const layersDraw = (value: string) => {
  if (TileLayer.value) {
    TileLayer.value.setMap(null)
  }
  TileLayer.value = new amap.value.TileLayer.WMS({
    url: `${wmsUrl}/geoserver/ty/wms`,
    blend: true, // 地图级别切换时，不同级别的图片是否进行混合
    tileSize: 256, // 加载WMS图层服务时，图片的分片大小
    dataZooms: [1, 20],
    zIndex: 100,
    params: {
      SERVICE: "WMS",
      VERSION: "1.1.1",
      REQUEST: 'GetMap',
      FORMAT: "image/png",
      TRANSPARENT: true,
      LAYERS: `ty:view_device_columns`,
      exceptions: 'application/vnd.ogc.se_inimage',
      SRS: 'EPSG:3857',
      STYLES: '',
      CQL_FILTER: value
    }
  })
  TileLayer.value.setMap(map.value)
}
//  关键字搜索
const enterQuery = () => {
  if (WarehouseStore.searchCondition.keyword) { //  关键字
    //  地图高亮
    layersDraw(`keys like '%25${WarehouseStore.searchCondition.keyword}%25'`)
    //  筛选列表数据
    WarehouseStore.boxSelectionDataTypeAjax()
  } else if (WarehouseStore.searchList.length > 0) {  //  自定义
    let str: string[] = []
    let obj: any = {}
    for (let i = 0; i < WarehouseStore.searchList.length; i++) {
      const item = WarehouseStore.searchList[i];
      if (!obj[item.id]) {
        obj[item.id] = []
      }
      if (item.filters.length > 0) {
        for (let j = 0; j < item.filters.length; j++) {
          const row = item.filters[j];
          obj[item.id].push(row)
        }
      }
    }
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        const item = obj[key];
        let sign: string[] = []
        for (let i = 0; i < item.length; i++) {
          const row = item[i];
          sign.push(`${row.fieldName}='${row.value}'`)
        }
        const signs = sign.join(' or ')
        str.push(`type like '${key}' and (${signs})`)
      }
    }
    layersDraw(str.join(' or '))
  } else if (WarehouseStore.searchCondition.searchParam.length > 0) {  //  高级
    let str: string[] = []
    for (let i = 0; i < WarehouseStore.searchCondition.searchParam.length; i++) {
      const element = WarehouseStore.searchCondition.searchParam[i];
      let type = GroupNum(element.tableName)
      for (let j = 0; j < element.filters.length; j++) {
        const item = element.filters[j];
        let sign: string[] = []
        for (let m = 0; m < item.childList.length; m++) {
          const val = item.childList[m];
          sign.push(`${val.fieldName}='${val.value}'`)
        }
        const signs = sign.join(` ${item.connect} `)
        if (item.connect === 'or') {
          str.push(`type like '${type}' and (${signs})`)
        } else {
          str.push(`type like '${type}' and ${signs}`)
        }
      }
    }
    layersDraw(str.join(' or '))
  } else {
    // TileLayer.value.setMap(null)
  }
}

//  框选样式
const drawPolygon = () => {
  if (!SettingStore.mouseToolStutas) return
  mouseTool.value.polygon({
    strokeColor: "#FF33FF",
    strokeWeight: 6,
    strokeOpacity: 0.2,
    fillColor: '#1791fc',
    fillOpacity: 0.4,
    // 线样式还支持 'dashed'
    strokeStyle: "solid",
    // strokeStyle是dashed时有效
    // strokeDasharray: [30,10],
  })
}
//  框选事件
const drawHandler = (event: any) => {
  const opts = event.obj._opts.path
  if (opts.length > 2) {
    let str = ''
    let array: string[] = []
    opts.forEach((item: any) => {
      str = item.join(' ')
      array.push(str)
    })
    array.push(array[0])
    let text = array.join(',')
    mouseTool.value.close(true)
    layersDraw(`WITHIN(geo, POLYGON((${text})))`)
    drawHandlerAjax(`POLYGON((${text}))`)
  }
}
//  通过框选状态取消选中点
watch(() => SettingStore.mouseToolStutas, (newVal) => {
  if (!newVal) {
    if (TileLayer.value) {
      TileLayer.value.setMap(null)
    }
    // 取消后清空数据
    WarehouseStore.clearData()
  }
})
//  框选后请求数据类型
import useWarehouseStore from '@/store/modules/warehouse'
const WarehouseStore = useWarehouseStore()
const drawHandlerAjax = (value: string) => {
  WarehouseStore.searchCondition = {
    WKTStr: value
  }
  WarehouseStore.boxSelectionDataTypeAjax()
}

defineExpose({
  map,
  drawPolygon,
  enterQuery,
  queryGeomAjax
})
</script>

<style scoped lang="scss">
.cons {
  position: relative;
  width: 100%;
  height: 100%;

  #map {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
}


.mapstyle {

  font-family: PingFangSC-Semibold, PingFang SC;
  font-weight: 600;
  color: #FFFFFF;

}
</style>